import router from "../router/index"; //引入router
import { userCenterBaseRoute, adminBaseRoute } from "../router/static"; //引入router
import { useMemberCenter } from "../store/memberCenter"; //用户中心仓库
import { useNavTabs } from "../store/navTabs"; //用户中心仓库
import { isNavigationFailure, NavigationFailureType } from "vue-router"; //引入router类型
import type { RouteRecordRaw, RouteLocationRaw } from "vue-router"; //引入router类型
import { ElNotification } from "element-plus"; //处理导航信息
import { isExternal } from "@/utils/common";

/**
 * 导航失败有错误消息的路由push
 * @param to — 导航位置，同 router.push
 * 如果导航被阻止，导致用户停留在同一个页面上，
 * 由 router.push 返回的 Promise 的解析值将是
 * Navigation Failure。否则，它将是一个 falsy 值(通常是 undefined)
 * 这样我们就可以区分我们导航是否离开了当前位置：
 */
export const routePush = async (to: RouteLocationRaw) => {
  console.log("to", to);
  try {
    // await是因为router.push是异步的情况
    const failureResult = await router.push(to);
    console.log("failureResult");

    /**
     * 要检查导航结果的性质，请使用 isNavigationFailure 函数
     *  if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
     *  给用户显示一个小通知showToast('You have unsaved changes, discard and leave anyway?')}
     * 如果你忽略第二个参数： isNavigationFailure(failure)，
     *  那么就只会检查这个 failure 是不是一个 Navigation Failure
     * 不同的 Navigation Failure:
     * aborted：在导航守卫中返回 false 中断了本次导航。
     * cancelled： 在当前导航还没有完成之前又有了一个新的导航。比如，在等待导航守卫的过程中又调用了 router.push。
     * duplicated：导航被阻止，因为我们已经在目标位置了。
     */
    if (isNavigationFailure(failureResult, NavigationFailureType.aborted)) {
      ElNotification({
        message: "导航警卫截获了！",
        type: "error",
      });
    } else if (
      isNavigationFailure(failureResult, NavigationFailureType.duplicated)
    ) {
      ElNotification({
        message: "我们已经在目标位置!",
        type: "warning",
      });
    } else if (
      isNavigationFailure(failureResult, NavigationFailureType.cancelled)
    ) {
      // ElNotification({
      //   message: "当前导航还没有完成!",
      //   type: "warning",
      // });
    }
  } catch (error) {
    ElNotification({
      message: "无效路由!",
      type: "error",
    });
    console.error(error);
  }
};

/**
 * 获取第一个菜单
 */
export const getFirstRoute = (
  routes: RouteRecordRaw[] //此时的routes中的meta.type=menu_type()
): false | RouteRecordRaw => {
  const routerPaths: string[] = [];
  const routers = router.getRoutes(); //router.getRoutes()获取静态以及addRoute()添加的路由记录
  // console.log("routes", routes, "routers", routers);
  routers.forEach((item) => {
    if (item.path) routerPaths.push(item.path);
  });
  let find: boolean | RouteRecordRaw = false; //默认第一个菜单没有子菜单
  for (const key in routes) {
    // console.log(
    //   "key",
    //   key,
    //   "routes[key].name",
    //   routes[key].name,
    //   "routes[key].path",
    //   routes[key].path,
    //   routerPaths
    // );
    //不为
    if (
      (routes[key].name != null || undefined) &&
      routerPaths.indexOf(routes[key].path) !== -1
    ) {
      return routes[key];
    } else if (routes[key].children && routes[key].children?.length) {
      find = getFirstRoute(routes[key].children!);
      if (find) return find;
    }
  }
  return find;
};
//获取第二个菜单
export const getSecondRoute = (
  routes: RouteRecordRaw[] //此时的routes中的meta.type=menu_type()
): false | RouteRecordRaw => {
  const routerPaths: string[] = [];
  const routers = router.getRoutes(); //router.getRoutes()获取静态以及addRoute()添加的路由记录
  routers.forEach((item) => {
    if (item.path) routerPaths.push(item.path);
  });
  let find: boolean | RouteRecordRaw = false; //默认第一个菜单没有子菜单
  for (const key in routes) {
    // console.log(
    //   "key",
    //   key,
    //   "routes[key].name",
    //   routes[key].name,
    //   "routes[key].path",
    //   routes[key].path,
    //   routerPaths
    // );
    //不为
    if (
      (routes[key].name != null || undefined) &&
      routerPaths.indexOf(routes[key].path) !== -1
    ) {
      return routes[key];
    } else if (routes[key].children && routes[key].children?.length) {
      find = getSecondRoute(routes[key].children!);
      if (find) return find;
    }
  }
  return find;
};

//处理会员中心的路由
export const handleMemberCenterRoute = (routes: any) => {
  /**
   * import.meta.globEager 已经弃用，请使用 import.meta.glob('*', { eager: true }) 来代替
   * 将views下frontend的所有.vue页面批量导入解析成以下格式:
   *  const viewsComponent = {
   * './src/foo.js': () => import('./src/foo.js'),
   * './src/bar.js': () => import('./src/bar.js')
   * }
   */
  const viewsComponent = import.meta.glob("/src/views/frontend/**/*.vue");
  /**
   * addRouteAll（）动态添加路由-带子路由
   * viewsComponent为{'./src/foo.js': () => import('./src/foo.js')}
   * routes是从后台获取的menu数组对象
   * userCenterBaseRoute为router文件夹下写的静态用户中心路由数据
   */
  addRouteAll(viewsComponent, routes, userCenterBaseRoute.name as string);

  //声明menuMemberCenterBaseRoute变量将静态路由修改为 /user/
  const menuMemberCenterBaseRoute =
    "/" + (userCenterBaseRoute.name as string) + "/";
  /**
   * handleMenuRule()
   * routes是从后台获取的menu数组对象
   * menuMemberCenterBaseRoute为 /user/
   */
  const menuRule = handleMenuRule(
    routes,
    menuMemberCenterBaseRoute,
    menuMemberCenterBaseRoute,
    "user"
  );

  const memberCenter = useMemberCenter();
  memberCenter.setViewRoutes(menuRule); //
  memberCenter.setShowHeadline(routes.length > 1 ? true : false);
};

//处理后台的路由
export const handleAdminRoute = (routes: any) => {
  // console.log("handleAdminRoute", routes);
  const viewsComponent = import.meta.glob("/src/views/backend/**/*.vue");
  addRouteAll(viewsComponent, routes, adminBaseRoute.name as string);
  console.log(" adminBaseRoute.name", adminBaseRoute.name);
  console.log(" viewsComponent", viewsComponent);
  const menuAdminBaseRoute = "/" + (adminBaseRoute.name as string) + "/";
  const menuRule = handleMenuRule(
    routes,
    menuAdminBaseRoute,
    menuAdminBaseRoute,
    "admin"
  );
  console.log("menuRule", menuRule);

  // 更新stores中的路由菜单数据
  const navTabs = useNavTabs();
  navTabs.setTabsViewRoutes(menuRule);
};

/**
 * 菜单处理
 */
const handleMenuRule = (
  routes: any,
  pathPrefix = "/",
  parent = "/",
  module = "admin"
) => {
  // console.log("parent", parent, "pathPrefix", pathPrefix, "module", module);
  const menuRule: RouteRecordRaw[] = [];
  const authNode: string[] = []; //权限节点
  for (const key in routes) {
    if (routes[key].extend == "add_rules_only") {
      continue;
    }
    if (routes[key].type == "menu" || routes[key].type == "menu_dir") {
      if (
        routes[key].type == "menu_dir" &&
        routes[key].children &&
        !routes[key].children.length
      ) {
        continue;
      }
      const currentPath =
        routes[key].menu_type == "link" || routes[key].menu_type == "iframe"
          ? routes[key].url
          : pathPrefix + routes[key].path;
      let children: RouteRecordRaw[] = [];
      if (routes[key].children && routes[key].children.length > 0) {
        children = handleMenuRule(
          routes[key].children,
          pathPrefix,
          currentPath,
          module
        );
      }
      menuRule.push({
        path: currentPath,
        name: routes[key].name,
        //!RouteRecordRaw类型() => import()
        // component: () => import("@" + routes[key].component),
        component: routes[key].component,
        meta: {
          title: routes[key].title,
          icon: routes[key].icon,
          keepalive: routes[key].keepalive,
          type: routes[key].menu_type,
          //! menu_type: routes[key].menu_type,
          menu_type: routes[key].type,
        },
        children: children,
      });
    } else {
      // 权限节点 举例：name:'SysM/dept/index' type为button
      authNode.push(pathPrefix + routes[key].name);
    }
  }
  if (authNode.length) {
    if (module == "admin") {
      //添加后台按钮权限节点
      const navTabs = useNavTabs();
      navTabs.setAuthNode(parent, authNode);
    } else if (module == "user") {
      //添加用户中心权限节点
      const memberCenter = useMemberCenter();
      memberCenter.setAuthNode(parent, authNode);
    }
  }
  return menuRule;
};

export const handleForRouyi = (routes: RouteRecordRaw[]) => {
  console.log("处理菜单数据", routes);

  const menuAdminBaseRoute = "/" + (adminBaseRoute.name as string) + "/";
  const menuRule = handleforRouyi(
    routes,
    menuAdminBaseRoute,
    menuAdminBaseRoute
  );
  const lastDataOfMenu = handleLast(menuRule);
  // 更新stores中的路由菜单数据
  const navTabs = useNavTabs();
  navTabs.setTabsViewRoutes(lastDataOfMenu);
};

//for rouyi
export const handleforRouyi = (routes: any, pathPrefix = "/", parent = "/") => {
  const menuRule: RouteRecordRaw[] = [];
  for (const key in routes) {
    const currentPath = routes[key].meta?.link
      ? routes[key].meta?.link
      : pathPrefix + routes[key].path;
    let children: RouteRecordRaw[] = [];
    if (routes[key].children && routes[key].children.length > 0) {
      children = handleforRouyi(routes[key].children, pathPrefix, currentPath);
    }
    // console.log("routes[key]", routes[key]);

    menuRule.push({
      path: currentPath,
      name: routes[key].name,
      component: routes[key].component,
      meta: {
        title: routes[key].meta?.title,
        // extend: route.extend,
        icon: routes[key].meta?.icon,
        noCache: routes[key].meta?.noCache, //原本为keepalive：route.meta.keepalive
        // menu_type: route.menu_type,
        link: routes[key].meta?.link,
        // url: route.url,
        addtab: true, //在tabs页面因为权限原因需要判断addtab是否为true
        hidden: routes[key].hidden,
      },
      children: children,
    });
  }
  return menuRule;
};
//处理路由中/符号问题
const handleLast = (data: RouteRecordRaw[]) => {
  const temp: RouteRecordRaw[] = [];
  for (const key in data) {
    data[key].path = data[key].path.replace("//", "/");
    temp.push(data[key]);
  }
  return temp;
};
//处理权限阶段
export const setAuthNodeRuoyi = (parent: string, data: any) => {
  const authNode: string[] = []; //权限节点

  let len = data.length;
  if (len > 1) {
    for (let i = 0; i < len; i++) {
      //regexp 具有全局标志 g，那么 replace() 方法将替换所有匹配的子串 否则，它只替换第一个匹配子串
      data[i] = parent + data[i].replace(/:/g, "/");
      authNode.push(data[i]);
      // const navTabs = useNavTabs();
      // navTabs.setAuthNode(parent, authNode);
    }
  } else {
    authNode.push(data[0]);
  }
  if (parent == "/admin/") {
    //添加后台按钮权限节点
    const navTabs = useNavTabs();
    navTabs.setAuthNode(parent, authNode);
  } else if (parent == "/user/") {
    //添加用户中心权限节点
    const memberCenter = useMemberCenter();
    memberCenter.setAuthNode(parent, authNode);
  }
};

export const beforeAddRouteAll = (data: RouteRecordRaw[]) => {
  return new Promise((resolve, reject) => {
    const temp: RouteRecordRaw[] = [];
    for (const key in data) {
      data[key].path = data[key].path.replace("/", "");
      temp.push(data[key]);
    }
    resolve(temp);
  }).catch((err) => {
    // ElNotification({
    //   type: "error",
    //   message: err,
    // });
  });
};
// 动态添加路由方法
/**
 *
 * @param viewsComponent  /src/views/backend/BigBoard/bigBoard2.vue: () => import("/src/views/backend/BigBoard/bigBoard2.vue")
 * @param routes
 * @param parentName
 */
export const addRouteAll = (
  viewsComponent: Record<string, { [key: string]: any }>,
  routes: any,
  parentName: string
) => {
  for (const idx in routes) {
    // if (routes[idx].extend == "add_menu_only") {
    //   continue;
    // }
    // if (
    //   routes[idx].type == "menu" &&
    //   ((routes[idx].menu_type == "tab" &&
    //     viewsComponent[routes[idx].component]) ||
    //     routes[idx].menu_type == "iframe")
    // ) {
    //   addRouteItem(viewsComponent, routes[idx], parentName);
    // }
    if (routes[idx].children && routes[idx].children.length > 0) {
      addRouteAll(viewsComponent, routes[idx].children, parentName);
    } else {
      addRouteItem(viewsComponent, routes[idx], parentName);
    }
  }
};

/**
 * 动态添加路由
 */
export const addRouteItem = (
  viewsComponent: Record<string, { [key: string]: any }>,
  route: any,
  parentName: string
) => {
  let path = "",
    component;

  if (route.menu_type == "iframe") {
    path = "/admin/iframe/" + encodeURIComponent(route.url);
    // component = () => import("@/layouts/common/router-view/iframe.vue");
  } else {
    path = parentName ? route.path : "/" + route.path;
    // component = viewsComponent[route.component].default;
    component = viewsComponent[route.component];
  }

  const routeBaseInfo: RouteRecordRaw = {
    path: path,
    name: route.name,
    component: component,
    meta: {
      title: route.meta.title,
      // extend: route.extend,
      icon: route.meta.icon,
      noCache: route.meta.noCache, //原本为keepalive：route.meta.keepalive
      // menu_type: route.menu_type,
      link: route.meta.link,
      // url: route.url,
      addtab: true, //在tabs页面因为权限原因需要判断addtab是否为true
    },
    children: [],
  };
  if (parentName) {
    router.addRoute(parentName, routeBaseInfo);
  } else {
    router.addRoute(routeBaseInfo);
  }
};

/**
 * 导航失败有错误消息的路由push
 * @param to — 导航位置，同 router.push
 */
//

// export const clickMenu = (menu: RouteRecordRaw) => {
//   switch (menu.meta?.type ) {
//     case "iframe":
//     case "tab":
//       routePush({ name: menu.name });
//       break;
//     case "link":
//       window.open(menu.path, "_blank");
//       break;
//     default:
//       ElNotification({
//         message: "utils.Navigation failed, the menu type is unrecognized!",
//         type: "error",
//       });
//       break;
//   }
// };
export const clickMenu = (menu: RouteRecordRaw) => {
  console.log("menu", menu, router);
  if (
    menu.path === "/admin/BigBoard/bigBoard1" ||
    menu.path === "/admin/BigBoard/bigBoard2"
  ) {
    const { href } = router.resolve({
      path: menu.path,
    });
    window.open(href, "_blank");
  } else {
    if (isExternal(menu.path)) {
      //外部链接与iframe
      window.open(menu.path, "_blank");
    } else {
      //路由菜单类型
      routePush({ name: menu.name });
    }
  }
};
/**
 * encodeURIComponent() 函数可把字符串作为 URI 组件进行编码
 *  encodeURIComponent(URIstring)  URIstring 必需为字符串，含有 URI 组件或其他要编码的文本
 * decodeURIComponent() 函数可把字符串作为 URI 组件进行解码
 *  decodeURIComponent(URIstring) URIstring 必需为字符串，含有 URI 组件或其他要解码的文本
 *  */

/**
 * 后台
 * 获取菜单的paths
 */
export const getMenuPaths = (menus: RouteRecordRaw[]): string[] => {
  let menuPaths: string[] = [];
  menus.forEach((item) => {
    menuPaths.push(item.path);
    if (item.children && item.children.length > 0) {
      menuPaths = menuPaths.concat(getMenuPaths(item.children));
    }
  });
  return menuPaths;
};
